#pragma once
#include <Winsock2.h>
#pragma comment(lib,"Ws2_32.lib")

#define DEF_SIZE 1024
#define DEF_IP_ADDR "127.0.0.1"
#define DEF_IP_PORT 0

class SocketServer;
class SocketClient;
class SockEvent;
struct SockBuffer{
    char * buffer;
    int len;
    SockBuffer():len(DEF_SIZE){
        buffer = new char[len];
    }
    SockBuffer(int l):len(l){
        buffer = new char[len];
    }
    ~SockBuffer(){
        delete[] buffer;
    }
    operator const char*() const{
        return buffer;
    }
    operator int() const{
        return len;
    }
};
class Socket
{
    friend SocketServer;
    friend SocketClient;
    friend SockEvent;
    struct DLL
    {
        WORD sockVersion;
        WSADATA wsdata;
        bool DLLErr;
        DLL(){
            //初始化DLL
            dll.sockVersion = MAKEWORD(2, 2);
            if(WSAStartup(dll.sockVersion, &dll.wsdata) != 0){
                dll.DLLErr = false;
            }else{
                dll.DLLErr = true;  //异常处理
            }
        }
        ~DLL(){
            WSACleanup();
        }
    };
protected:
    static DLL dll;
    SOCKET Sock;
    sockaddr_in sockAddr;
    short err;
    void setAddr(const char* addr,int port);
public:
    virtual int SockStartup()=0;
    virtual int send(SockBuffer*)=0;
    virtual int recv(SockBuffer*)=0;
    Socket();
    Socket(const char* addr,int port);
    ~Socket();
};

Socket::DLL Socket::dll;

void Socket::setAddr(const char* addr,int port)
{
    sockAddr.sin_family = AF_INET;
    sockAddr.sin_port = htons(port);
    sockAddr.sin_addr.S_un.S_addr = inet_addr(addr);
}

Socket::Socket()
{
    if(err!=0){return;}
    setAddr(DEF_IP_ADDR,DEF_IP_PORT);
}

Socket::Socket(const char* addr,int port)
{
    if(err!=0){return;}
    setAddr(addr,port);
}

Socket::~Socket()
{
    closesocket(Sock);
}
